#!/bin/bash

# 显示用法信息
usage() {
    cat << EOF
用法: $0 {start|stop|restart|status|logs|check-logs} [选项]

操作:
  start       启动所有Docker Compose服务
  stop        停止所有Docker Compose服务
  restart     重启所有Docker Compose服务
  status      查看所有Docker Compose服务状态
  logs        查看所有服务的日志（默认500行）
  check-logs  检查所有服务的日志中是否有异常（默认500行）

选项:
  -d, --directory DIR   指定要操作的目录（默认: 当前目录）
  -e, --exclude DIR     排除指定的目录（可多次使用）
  -n, --lines NUM       指定要显示的日志行数（默认: 500）
  -p, --pattern PATTERN 指定检查日志时使用的模式（默认: error\|exception\|fail\|warn）
  -h, --help            显示此帮助信息

示例:
  $0 start                     # 启动当前目录下的所有服务
  $0 stop -d ./project1        # 停止指定目录下的服务
  $0 logs -n 1000              # 查看所有服务的最近1000行日志
  $0 check-logs -p "timeout"   # 检查所有服务日志中是否有timeout异常
  $0 status -e ./project2      # 查看状态，排除指定目录
  $0 restart -d ./project1 -e ./project1/test  # 重启项目，排除子目录
EOF
    exit 1
}

# 初始化变量
TARGET_DIR="."
EXCLUDE_DIRS=()
LOG_LINES=500
LOG_PATTERN="error\|exception\|fail\|warn"
OPERATION=""

# 改进的参数解析，处理 --n 等错误格式
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            start|stop|restart|status|logs|check-logs)
                OPERATION="$1"
                shift
                ;;
            -d|--directory)
                if [ -z "$2" ] || [[ "$2" == -* ]]; then
                    echo "错误: --directory 需要指定一个目录参数"
                    exit 1
                fi
                TARGET_DIR="$2"
                shift 2
                ;;
            -e|--exclude)
                if [ -z "$2" ] || [[ "$2" == -* ]]; then
                    echo "错误: --exclude 需要指定一个目录参数"
                    exit 1
                fi
                EXCLUDE_DIRS+=("$2")
                shift 2
                ;;
            -n|--lines)
                if [ -z "$2" ] || [[ "$2" == -* ]]; then
                    echo "错误: --lines 需要指定一个数字参数"
                    exit 1
                fi
                if ! [[ "$2" =~ ^[0-9]+$ ]]; then
                    echo "错误: --lines 参数必须是数字"
                    exit 1
                fi
                LOG_LINES="$2"
                shift 2
                ;;
            --n) # 处理错误的 --n 格式
                echo "警告: --n 不是有效选项，您可能想使用 -n 或 --lines"
                if [ -z "$2" ] || [[ "$2" == -* ]]; then
                    echo "错误: -n/--lines 需要指定一个数字参数"
                    exit 1
                fi
                if ! [[ "$2" =~ ^[0-9]+$ ]]; then
                    echo "错误: -n/--lines 参数必须是数字"
                    exit 1
                fi
                LOG_LINES="$2"
                shift 2
                ;;
            -p|--pattern)
                if [ -z "$2" ] || [[ "$2" == -* ]]; then
                    echo "错误: --pattern 需要指定一个搜索模式"
                    exit 1
                fi
                LOG_PATTERN="$2"
                shift 2
                ;;
            -h|--help)
                usage
                ;;
            *)
                echo "未知选项: $1"
                usage
                ;;
        esac
    done
}

# 解析参数
parse_arguments "$@"

# 验证操作参数
if [ -z "$OPERATION" ]; then
    echo "错误: 必须指定操作 (start|stop|restart|status|logs|check-logs)"
    usage
fi

# 检查目录是否存在
if [ ! -d "$TARGET_DIR" ]; then
    echo "错误: 目录 '$TARGET_DIR' 不存在"
    exit 1
fi

# 构建find排除参数
EXCLUDE_ARGS=()
for exclude_dir in "${EXCLUDE_DIRS[@]}"; do
    # 确保排除目录是相对路径
    if [[ "$exclude_dir" == /* ]]; then
        # 如果是绝对路径，转换为相对路径
        exclude_dir=$(realpath --relative-to="$TARGET_DIR" "$exclude_dir" 2>/dev/null || echo "$exclude_dir")
    fi
    EXCLUDE_ARGS+=(-not -path "*/$exclude_dir/*")
done

echo "开始执行操作: $OPERATION"
echo "目标目录: $TARGET_DIR"
if [ ${#EXCLUDE_DIRS[@]} -gt 0 ]; then
    echo "排除目录: ${EXCLUDE_DIRS[*]}"
fi
if [[ "$OPERATION" == "logs" || "$OPERATION" == "check-logs" ]]; then
    echo "日志行数: $LOG_LINES"
fi
if [[ "$OPERATION" == "check-logs" ]]; then
    echo "检查模式: $LOG_PATTERN"
fi
echo "----------------------------------------"

# 递归查找所有 docker-compose.yml 文件并处理
while IFS= read -r -d '' file; do
    dir=$(dirname "$file")
    # 计算目录深度（路径中'/'的数量）
    depth=$(tr -cd '/' <<< "$dir" | wc -c)
    printf "%d\t%s\n" "$depth" "$dir"
done < <(find "$TARGET_DIR" -name docker-compose.yml "${EXCLUDE_ARGS[@]}" -print0 2>/dev/null) | \
case "$OPERATION" in
    # 启动和状态检查按深度升序处理
    start|status|logs|check-logs)
        sort -n -k1 | cut -f2-
        ;;
    # 停止和重启时按深度降序处理（用于依赖关系）
    stop|restart)
        sort -nr -k1 | cut -f2-
        ;;
esac | while IFS= read -r dir; do
    depth=$(tr -cd '/' <<< "$dir" | wc -c)

    echo "[$OPERATION] ${dir} (深度: $depth)"

    # 执行操作
    case "$OPERATION" in
        start)
            (cd "$dir" && {
                if docker-compose --compatibility up -d; then
                    echo "  √ 启动成功"
                else
                    echo "  × 启动失败! 检查日志: docker-compose logs"
                fi
            })
            ;;
        stop)
            (cd "$dir" && {
                if docker-compose --compatibility down; then
                    echo "  √ 停止成功"
                else
                    echo "  × 停止失败! 检查日志: docker-compose logs"
                fi
            })
            ;;
        restart)
            # 重启操作：先停止再启动
            (cd "$dir" && {
                echo "  停止服务..."
                if docker-compose --compatibility down; then
                    echo "  √ 停止成功"
                else
                    echo "  × 停止失败! 检查日志: docker-compose logs"
                fi
                echo "  启动服务..."
                if docker-compose --compatibility up -d; then
                    echo "  √ 启动成功"
                else
                    echo "  × 启动失败! 检查日志: docker-compose logs"
                fi
            })
            ;;
        status)
            (cd "$dir" && {
                echo "服务状态:"
                docker-compose --compatibility ps
            })
            ;;
        logs)
            (cd "$dir" && {
                echo "项目的最近${LOG_LINES}行日志:"
                docker-compose --compatibility logs --tail="$LOG_LINES"
            })
            ;;
        check-logs)
            (cd "$dir" && {
                echo "检查项目日志中是否有异常..."
                # 移除local关键字，因为它在子shell中不可用
                logs=$(docker-compose --compatibility logs --tail="$LOG_LINES" 2>&1)

                if echo "$logs" | grep -i "$LOG_PATTERN" > /dev/null; then
                    echo "  ⚠ 发现异常日志:"
                    echo "$logs" | grep -i --color=always "$LOG_PATTERN" | head -10
                    echo "  (显示前10条匹配的日志)"
                else
                    echo "  √ 未发现异常日志"
                fi
            })
            ;;
    esac
    echo "----------------------------------------"
done

echo "✅ 所有服务操作完成: $OPERATION"
